import datetime
import calendar
import json

from django.shortcuts import render, redirect, get_object_or_404
from django.http import HttpResponseRedirect, Http404, HttpResponse
from django.urls import reverse_lazy, reverse
from django.views.generic import CreateView, UpdateView, ListView, DetailView
from django.utils import timezone
from django.core.serializers.json import DjangoJSONEncoder
from django.forms import formset_factory, modelformset_factory, BaseFormSet

from .models import LabLog, ShiftSchedule
from .forms import LabLogModelForm, ShiftScheduleModelForm


class LabLogListView(ListView):
    model = LabLog
    # context_object_name = 'lablogs'
    template_name = 'logs/lablog_list.html'

    def get_context_data(self, *, object_list=None, **kwargs):
        context = super(LabLogListView, self).get_context_data(**kwargs)
        now = timezone.localtime(timezone.now())
        has_today_am_log = LabLog.objects.filter(log_date=now.date(), time_slot=1).exists()
        has_today_pm_log = LabLog.objects.filter(log_date=now.date(), time_slot=2).exists()

        context['now'] = now
        context['has_today_am_log'] = has_today_am_log  # 是否已经添加上午日志
        context['has_today_pm_log'] = has_today_pm_log  # 是否已经添加下午日志
        context['url'] = 'lablog_list'
        return context


class LabLogDetailView(DetailView):
    model = LabLog
    context_object_name = 'lablog'
    template_name = 'logs/lablog_detail.html'


class CreateLabLogView(CreateView):
    model = LabLog
    form_class = LabLogModelForm
    success_url = reverse_lazy('lablog_list')
    template_name = 'logs/create_or_update_lablog.html'

    def get(self, request, *args, **kwargs):
        try:
            date = datetime.datetime.strptime(kwargs.get('date') + "+0800", '%Y%m%d%z')
            slot = int(kwargs.get('slot'))
            print(slot)
        except ValueError:
            raise Http404("日期格式不正确！")

        if timezone.localtime(date) > timezone.localtime(timezone.now()) \
                or timezone.localtime(date) + timezone.timedelta(hours=33) < timezone.localtime(timezone.now()):
            raise Http404("超出日志提交时限！")

        if slot == 2 and timezone.localtime(timezone.now()) <= (
                timezone.localtime(date) + timezone.timedelta(hours=12)):
            raise Http404("日志还不能添加！")

        log_exsist = LabLog.objects.filter(log_date=date, time_slot=slot).exists()

        if log_exsist:
            return redirect('update_lablog', date=self.kwargs['date'], slot=self.kwargs['slot'])

        return super(CreateLabLogView, self).get(request, *args, **kwargs)

    def get_form_kwargs(self):
        kwargs = super(CreateLabLogView, self).get_form_kwargs()
        log_date = datetime.datetime.strptime(self.kwargs.get('date'), '%Y%m%d')
        time_slot = int(self.kwargs.get('slot'))

        kwargs.update({
            'log_date': log_date,
            'time_slot': time_slot,
            # 'create_or_update': 1,
        })
        return kwargs

    def get_context_data(self, **kwargs):
        context = super(CreateLabLogView, self).get_context_data(**kwargs)
        context['log_date'] = datetime.datetime.strptime(self.kwargs.get('date'), '%Y%m%d')
        context['time_slot'] = int(self.kwargs.get('slot'))
        print(context['time_slot'])
        context['create_or_update'] = 1
        context['url'] = 'lablog_list'
        return context

    def form_valid(self, form):
        lablog = form.save(commit=False)
        if self.request.user:
            lablog.created_by = self.request.user
        lablog.created_at = timezone.now()
        lablog.log_date = datetime.datetime.strptime(self.kwargs.get('date'), '%Y%m%d')
        lablog.time_slot = int(self.kwargs.get('slot'))
        lablog.save()
        return super(CreateLabLogView, self).form_valid(form)


class UpdateLabLogView(UpdateView):
    model = LabLog
    form_class = LabLogModelForm
    success_url = reverse_lazy('lablog_list')
    template_name = 'logs/create_or_update_lablog.html'

    def get_form_kwargs(self):
        kwargs = super(UpdateLabLogView, self).get_form_kwargs()
        log_date = self.object.log_date
        time_slot = self.object.time_slot
        kwargs.update({
            'log_date': log_date,
            'time_slot': time_slot,
        })
        return kwargs

    def get_context_data(self, **kwargs):
        context = super(UpdateLabLogView, self).get_context_data(**kwargs)
        # context['log_date'] = datetime.datetime.strptime(self.kwargs.get('date'), '%Y%m%d')
        # context['time_slot'] = int(self.kwargs.get('slot'))
        context['log_date'] = self.object.log_date
        context['time_slot'] = self.object.time_slot
        context['create_or_update'] = 2
        context['url'] = 'lablog_list'
        return context

    def get_object(self, queryset=None):
        # 日期字符串格式是否正确
        try:
            date = datetime.datetime.strptime(self.kwargs['date'] + "+0800", '%Y%m%d%z')
        except ValueError:
            raise Http404("日期格式不正确！")

        slot = int(self.kwargs.get('slot'))
        # print(timezone.localtime(timezone.now()) - timezone.localtime(date))
        # print(timezone.localtime(timezone.now()))
        # print(timezone.localtime(date))

        # 判断添加日志的日期为当天到第二天早上09:00
        if timezone.localtime(date) <= timezone.localtime(timezone.now()) \
                and timezone.localtime(date) + timezone.timedelta(hours=33) <= timezone.localtime(timezone.now()):
            # if timezone.timedelta(seconds=0) > (timezone.localtime(timezone.now()) - timezone.localtime(date)) or (
            #         timezone.localtime(timezone.now()) - timezone.localtime(date)) > timezone.timedelta(hours=33):
            raise Http404("超出日志修改时限！")

        obj = LabLog.objects.get(log_date=date, time_slot=slot)
        return obj

    def form_valid(self, form):
        lablog = form.save(commit=False)
        lablog.updated_by = self.request.user
        lablog.last_updated = timezone.now()
        lablog.save()
        return super(UpdateView, self).form_valid(form)


def bulk_create_schedule_by_month(request, year, month):
    print(year)
    print(month)
    template_name = 'logs/create_schedule_by_month.html'
    _, days_in_month = calendar.monthrange(year, month)
    initial_data = [{'duty_date': datetime.date(year, month, i)} for i in range(1, days_in_month + 1)]
    formset_params = {}
    formset_params['initial'] = initial_data

    # ScheduleFormset = modelformset_factory(model=ShiftSchedule, form=ShiftScheduleModelForm, max_num=days_in_month,
    #                                        min_num=days_in_month)
    ScheduleFormset = formset_factory(form=ShiftScheduleModelForm, max_num=days_in_month, min_num=days_in_month)
    formsets = ScheduleFormset(ShiftSchedule.objects.none())

    if request.method == 'POST':
        formsets = ScheduleFormset(request.POST, **formset_params)
        if formsets.is_valid():
            for form in formsets:
                if form.cleaned_data.get('duty_date'):
                    form.save()

            return redirect('show_schedule', year=year, month=month)
    else:
        formsets = ScheduleFormset(**formset_params)

    return render(request, template_name=template_name, context={'formsets': formsets})


def show_schedule_by_month(request, year, month):
    template_name = 'logs/show_schedule_by_month.html'
    schedule_by_month = ShiftSchedule.objects.filter(duty_date__year=year, duty_date__month=month).all()
    return render(request, template_name=template_name, context={'schedule_by_month': schedule_by_month})


def ajax_server_now(request):
    '''
    提供ajax定时获取服务器时间
    :param request:
    :return:
    '''
    if request.method == "GET":
        name_dict = {'server_time': timezone.localtime(timezone.now())}
        return HttpResponse(json.dumps(name_dict, sort_keys=True, indent=1, cls=DjangoJSONEncoder),
                            content_type='application/json')
